#include "shape.h"

#include <sys/types.h>
#include <dirent.h>

void
shape_find_xml_shape(xmlNode * a_node, xmlNode **xml_shape)
{
	xmlNode *tmp_node = NULL;
    xmlNode *cur_node = NULL;
    for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
            if (strcmp(cur_node->name, "g") == 0) {
				for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next) {
					if (strcmp(cur_node->name, "path") == 0) {
						*xml_shape = cur_node;
					}
				}
				break;
            }
        }
        shape_find_xml_shape(cur_node->children, xml_shape);
    }
}

inline void
get_coords_from_string(char *str,
					   double *a,
					   double *b)
{
	char *ch;
	char tmp_str[10];
	int i = 0;

	while (*str != '\0') {
		if (*str == ',') {
			tmp_str[i] = 0;
			i = 0;
			ch = strchr(tmp_str, '.');
			*ch = ',';
			*a = atof(tmp_str);
			str++;
		}
		tmp_str[i] = *str;
		str++;
		i++;
	}
	tmp_str[i] = 0;
	ch = strchr(tmp_str, '.');
	*ch = ',';
	*b = atof(tmp_str);
}

void
shape_load_dir(char *path)
{
	DIR *dir;
	char full_path[256];
	struct dirent *ep;
	shape_t *shape;
	char filename_defs[256];
	dir = opendir(path);
	if (dir != NULL) {
		while (ep = readdir(dir)) {
			if ((strcasestr(ep->d_name, ".svg") == NULL) ||
			    (strcasestr(ep->d_name, ".svg.defs") != NULL))
				continue;
			sprintf(full_path, "%s/%s", path, ep->d_name);
			sprintf(filename_defs, "%s.defs", full_path);
			shape = shape_load_from_file(full_path);
			if (shape_load_defs_from_file(shape, filename_defs) == -1)
				printf("Error loading shape definitions!\n");
			else {
				shape_add_to_library(shape);
				//printf("Width: %f, height: %f\n", shape->w, shape->h);

			}
		}
	}
	closedir(dir);
}

int
shape_load_defs_from_file(shape_t *shape,
						  char *filename_defs)
{
	GKeyFile *keyfile;
	char *w_str, *h_str, *t_str = NULL;
	GError *error = NULL;
	double x, y;
	
	keyfile = g_key_file_new();
	if (!g_key_file_load_from_file(keyfile, filename_defs, G_KEY_FILE_NONE, &error)) {
		printf("* error: %s\n", error->message);
		return -1;
	}

	w_str = g_key_file_get_value(keyfile, "defs", "width", NULL);
	h_str = g_key_file_get_value(keyfile, "defs", "height", NULL);
	t_str = g_key_file_get_value(keyfile, "defs", "translate", NULL);

	shape->w = atof(w_str);
	shape->h = atof(h_str);
	if (t_str) {
		get_coords_from_string(t_str, &x, &y);
		shape->translate_x = x;
		shape->translate_y = y;
		printf("Found translate %f, %f\n", x, y);
	} else {
		shape->translate_x = 0;
		shape->translate_y = 0;

	}

	return 0;
}

shape_t *
shape_load_from_file(char *filename)
{
	shape_t *shape;
	xmlDoc *doc = NULL;
    xmlNode *root_element = NULL;
    xmlNode *svg_shape, *cur_prop;
	GScanner *scanner;
	char *line, *orig, *token;
	char *tok, *token_tmp;

    LIBXML_TEST_VERSION
    
    doc = xmlReadFile(filename, NULL, 0);
    if (doc == NULL) 
        return NULL;
    /*Get the root element node */
    root_element = xmlDocGetRootElement(doc);
    shape_find_xml_shape(root_element, &svg_shape);

	shape = g_malloc(sizeof(shape_t));
	strcpy(shape->filename, filename);
	shape->x = shape->y = -1;
	shape->d = NULL;
	shape->text = NULL;
	shape->conn_shape = NULL;
	shape->line_width = 1;
	shape->shape_type = SHAPE_TYPE_PATH;
	strcpy(shape->stroke, "#000000");

	for (cur_prop = svg_shape->properties; cur_prop; cur_prop = cur_prop->next) {
		if (strcmp(cur_prop->name, "id") == 0) {
			strncpy(shape->ID, cur_prop->children->content, 32);
		}
		else if (strcmp(cur_prop->name, "d") == 0) {
			line = g_malloc(strlen(cur_prop->children->content) + 1);
			strcpy(line, cur_prop->children->content);
			orig = line;
			token = strtok(line, " ");
			tok = g_malloc(strlen(token) + 1);
			strcpy(tok, token);
			shape->d = g_list_append(shape->d, tok);

			while ((token = strtok(NULL, " ")) != NULL) {
				tok = g_malloc(strlen(token) + 1);
				strcpy(tok, token);
				shape->d = g_list_append(shape->d, tok);
			}

			orig = line;
			g_free(line);
		}
		else if (strcmp(cur_prop->name, "style") == 0) {
			line = g_malloc(strlen(cur_prop->children->content) + 1);
			strcpy(line, cur_prop->children->content);
			orig = line;
			token = strtok(line, ";");
			token_tmp = token;
			if (strstr(token, "fill:") == token) {
				token += 5;
				strcpy(shape->fill, token);
			}
			token = token_tmp;
			while ((token = strtok(NULL, ";")) != NULL) {
				if (strstr(token, "stroke:") == token) {
					token += 7;
					strcpy(shape->stroke, token);
				}
				else if (strstr(token, "stroke-width") == token) {
					token += 13;
					shape->line_width = atoi(token);
				}
				token = token_tmp;
			}

			orig = line;
			g_free(line);

		}

	}
	g_print("fill: %s\n", shape->fill);
	if (strcmp(shape->fill, "none") == 0)
		strcpy(shape->fill, "#ffffff");
    xmlFreeDoc(doc);
    xmlCleanupParser();
	return shape;
}

void
shape_add_to_library(shape_t *shape)
{
	shape_library = g_list_append(shape_library, shape);
}

void
shape_change_width(shape_t *shape,
				   double width)
{
	GList *d = shape->d;
	char *ch, tmp_w[10], *data;
	int i;
	double w, new_w;

	for (; d; d = d->next) {
		data = (char *)d->data;
		if ((strcmp(data, "M") == 0) ||
		    (strcmp(data, "L") == 0) ||
			(strcmp(data, "z") == 0))
			continue;
		for (i = 0; i < 10; i++) {
			if (data[i] == ',')
				break;
			tmp_w[i] == data[i];
		}
		data[i] = 0;
		ch = strchr(data, '.');
		if (ch)
				*ch = ',';
		w = atof(data);
	}
}

void
shape_change_text(shape_t *shape,
				  char *text)
{
//	GdkRectangle rect = {1, 1, 400, 400};

	if (!shape->text)
		shape->text = g_malloc(256);
	strncpy(shape->text, text, 256);
}

